#!/usr/bin/env python3
"""
光标监控库的Python绑定
使用ctypes调用C库函数
"""

import ctypes
import ctypes.util
from ctypes import Structure, POINTER, c_int, c_ulong, c_void_p
import os
import sys
from typing import Optional, Tuple

# 定义结构体对应C的CursorStatus
class CursorStatus(Structure):
    _fields_ = [
        ("x", c_int),
        ("y", c_int),
        ("cursor_id", c_ulong),
        ("width", c_int),
        ("height", c_int),
        ("is_visible", c_int)
    ]

class CursorMonitor:
    """光标监控库的Python封装"""
    
    def __init__(self, lib_path: Optional[str] = None):
        """
        初始化光标监控库
        
        Args:
            lib_path: 库文件路径，如果为None则自动查找
        """
        self._lib = None
        self._display = None
        self._load_library(lib_path)
        self._setup_function_prototypes()
        
    def _load_library(self, lib_path: Optional[str]):
        """加载C库"""
        if lib_path is None:
            # 尝试自动查找库文件
            possible_paths = [
                "./libcursormonitor.so",
                "/usr/local/lib/libcursormonitor.so",
                "/usr/lib/libcursormonitor.so"
            ]
            
            for path in possible_paths:
                if os.path.exists(path):
                    lib_path = path
                    break
            else:
                raise FileNotFoundError("未找到 libcursormonitor.so，请指定库路径")
        
        if not os.path.exists(lib_path):
            raise FileNotFoundError(f"库文件不存在: {lib_path}")
            
        self._lib = ctypes.CDLL(lib_path)
        print(f"成功加载库: {lib_path}")
        
    def _setup_function_prototypes(self):
        """设置函数原型"""
        # cursor_monitor_init
        self._lib.cursor_monitor_init.restype = c_void_p
        self._lib.cursor_monitor_init.argtypes = []
        
        # cursor_monitor_get_status
        self._lib.cursor_monitor_get_status.restype = POINTER(CursorStatus)
        self._lib.cursor_monitor_get_status.argtypes = [c_void_p]
        
        # cursor_monitor_get_id
        self._lib.cursor_monitor_get_id.restype = c_ulong
        self._lib.cursor_monitor_get_id.argtypes = [c_void_p]
        
        # cursor_monitor_get_position
        self._lib.cursor_monitor_get_position.restype = c_int
        self._lib.cursor_monitor_get_position.argtypes = [c_void_p, POINTER(c_int), POINTER(c_int)]
        
        # cursor_monitor_free_status
        self._lib.cursor_monitor_free_status.restype = None
        self._lib.cursor_monitor_free_status.argtypes = [POINTER(CursorStatus)]
        
        # cursor_monitor_cleanup
        self._lib.cursor_monitor_cleanup.restype = None
        self._lib.cursor_monitor_cleanup.argtypes = [c_void_p]
        
        # cursor_monitor_xfixes_available
        self._lib.cursor_monitor_xfixes_available.restype = c_int
        self._lib.cursor_monitor_xfixes_available.argtypes = [c_void_p]
        
        # cursor_monitor_get_version
        self._lib.cursor_monitor_get_version.restype = ctypes.c_char_p
        self._lib.cursor_monitor_get_version.argtypes = []
    
    def init(self) -> bool:
        """
        初始化库
        
        Returns:
            bool: 成功返回True，失败返回False
        """
        self._display = self._lib.cursor_monitor_init()
        return self._display is not None
    
    def cleanup(self):
        """清理资源"""
        if self._display:
            self._lib.cursor_monitor_cleanup(self._display)
            self._display = None
    
    def get_status(self) -> Optional[CursorStatus]:
        """
        获取完整的光标状态
        
        Returns:
            CursorStatus: 光标状态信息，失败返回None
        """
        if not self._display:
            raise RuntimeError("库未初始化，请先调用init()")
        
        status_ptr = self._lib.cursor_monitor_get_status(self._display)
        if status_ptr:
            status = status_ptr.contents
            # 复制数据后立即释放
            result = CursorStatus(
                x=status.x,
                y=status.y,
                cursor_id=status.cursor_id,
                width=status.width,
                height=status.height,
                is_visible=status.is_visible
            )
            self._lib.cursor_monitor_free_status(status_ptr)
            return result
        return None
    
    def get_cursor_id(self) -> int:
        """
        获取光标ID
        
        Returns:
            int: 光标ID，失败返回0
        """
        if not self._display:
            raise RuntimeError("库未初始化，请先调用init()")
        
        return self._lib.cursor_monitor_get_id(self._display)
    
    def get_position(self) -> Optional[Tuple[int, int]]:
        """
        获取光标位置
        
        Returns:
            Tuple[int, int]: (x, y)坐标，失败返回None
        """
        if not self._display:
            raise RuntimeError("库未初始化，请先调用init()")
        
        x = c_int()
        y = c_int()
        success = self._lib.cursor_monitor_get_position(self._display, ctypes.byref(x), ctypes.byref(y))
        if success:
            return (x.value, y.value)
        return None
    
    def is_xfixes_available(self) -> bool:
        """
        检查XFixes扩展是否可用
        
        Returns:
            bool: 可用返回True
        """
        if not self._display:
            raise RuntimeError("库未初始化，请先调用init()")
        
        return bool(self._lib.cursor_monitor_xfixes_available(self._display))
    
    def get_version(self) -> str:
        """
        获取库版本
        
        Returns:
            str: 版本字符串
        """
        version_bytes = self._lib.cursor_monitor_get_version()
        return version_bytes.decode('utf-8') if version_bytes else "Unknown"
    
    def __enter__(self):
        """上下文管理器入口"""
        if not self.init():
            raise RuntimeError("初始化失败")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """上下文管理器出口"""
        self.cleanup()

# 简化使用函数
def get_cursor_id() -> int:
    """快速获取光标ID（一次性使用）"""
    with CursorMonitor() as monitor:
        return monitor.get_cursor_id()

def get_cursor_position() -> Optional[Tuple[int, int]]:
    """快速获取光标位置（一次性使用）"""
    with CursorMonitor() as monitor:
        return monitor.get_position()

def get_cursor_status() -> Optional[CursorStatus]:
    """快速获取完整光标状态（一次性使用）"""
    with CursorMonitor() as monitor:
        return monitor.get_status()